package com.example.origin.resttemplate.util;

import lombok.experimental.UtilityClass;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;


/**
 * @author yutao.zhang
 * @create 2022-07-18 16:11
 **/
@UtilityClass
public class RestUtil {

    public HttpEntity<?> createHttpEntity(Map<String, String> headerMap) {
        return createHttpEntity(null,headerMap);
    }

    private LinkedMultiValueMap<String, String> getMultiValueMap(Map<String, String> map) {
        LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        if (map !=null){
            map.forEach(headers::add);
        }
        return headers;
    }

    public <T> HttpEntity<T> createHttpEntity(T body, Map<String, String> headerMap) {
        LinkedMultiValueMap<String, String> headers = getMultiValueMap(headerMap);
        return new HttpEntity<>(body, headers);
    }

    public String urlParams(String urlPrefix, MultiValueMap<String, String> multiValueMap) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(urlPrefix)
                .queryParams(multiValueMap);
        return builder.build().toUriString();
    }

    public String urlParams(String urlPrefix, Map<String, String> paramMap) {
        if (paramMap==null){
            return urlPrefix;
        }
        LinkedMultiValueMap<String, String> multiValueMap = getMultiValueMap(paramMap);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(urlPrefix)
                .queryParams(multiValueMap);
        return builder.build().toUriString();
    }

    public <T> ResponseEntity<T> restGet(RestTemplate restTemplate,String urlPrefix,
                                                                               Map<String, String> paramMap,
                                                                               Map<String, String> headerMap,ParameterizedTypeReference<T> responseType) {
        return restDo(restTemplate,HttpMethod.GET, urlPrefix, paramMap, null, headerMap, responseType);
    }

    public <T> ResponseEntity<T> restGet(RestTemplate restTemplate,String url) {
        return RestUtil.restGet(restTemplate,  url, null, null,
                new ParameterizedTypeReference<T>() {
                });

    }


    public <P,T> ResponseEntity<T> restPost(RestTemplate restTemplate,String urlPrefix,
                                         Map<String, String> paramMap,
                                         P paramEntity,
                                         Map<String, String> headerMap,ParameterizedTypeReference<T> responseType) {
        return restDo(restTemplate,HttpMethod.POST, urlPrefix, paramMap, paramEntity, headerMap, responseType);
    }

    public <P, T> ResponseEntity<T> restDo(RestTemplate restTemplate, HttpMethod httpMethod,
                                           String urlPrefix,
                                           Map<String, String> paramMap,
                                           P paramEntity, Map<String, String> headerMap, ParameterizedTypeReference<T> responseType) {
        String url = urlParams(urlPrefix, paramMap);
        HttpEntity<?> httpEntity = createHttpEntity(paramEntity, headerMap);
        return restTemplate.exchange(
                url,
                httpMethod, httpEntity, responseType);
    }

    public <P,T> ResponseEntity<T> restPost(RestTemplate restTemplate,String url,
                                            P paramEntity,
                                            Map<String, String> headerMap,ParameterizedTypeReference<T> responseType) {
        return restDo(restTemplate,HttpMethod.POST, url, null, paramEntity, headerMap, responseType);
    }





}
